package com.hongyun.tms.common.utils;

import com.hongyun.tms.infra.ApplicationContextUtil;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class GenerateNumberUtil {

    private static final DateTimeFormatter DATE_YYYYMMDD_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * 生成指定长度的编号，格式为：年月日+指定长度的递增编号
     * 如传入了长度为3， 今天为2024-01-15  则会生成 20240115001...当日依次递增
     * @param redisPrefix Redis键前缀
     * @param noLength    生成的编号长度
     * @return 生成的编号
     */
    public static String generateNoByCurrentDate(String redisPrefix, int noLength) {
        StringRedisTemplate redisTemplate = ApplicationContextUtil.getBean(StringRedisTemplate.class);

        LocalDate today = LocalDate.now();
        String datePart = today.format(DATE_YYYYMMDD_FORMATTER); // 格式：202111005

        // Redis键的生成与日期相关，每天都会生成一个新的Redis键，因为键名包含了当天的日期
        String redisKey = redisPrefix + datePart;

        // 如果Redis键不存在（即新的一天开始时），Redis会将其初始化为0，然后递增1。
        // 所以，每天的第一次调用increment方法时，返回值会是1。
        Long increment = redisTemplate.opsForValue().increment(redisKey);

        // 为了确保每天的键值从01重新开始，设置Redis键在一天结束时过期，即0点
        LocalDateTime endOfDay = today.plusDays(1).atStartOfDay();
        redisTemplate.expireAt(redisKey, Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()));

        // 生成指定长度的编号格式
        String formatString = "%0" + noLength + "d";
        String incrementedPart = String.format(formatString, increment);

        return datePart + incrementedPart;
    }
}
